﻿
Imports System.Runtime.InteropServices
Imports osi.root.constants

Public Module _int_bytes
    Sub New()
        k_assert(sizeof_int8 = sizeof_uint8)
        k_assert(sizeof_int16 = sizeof_uint16)
        k_assert(sizeof_int32 = sizeof_uint32)
        k_assert(sizeof_int64 = sizeof_uint64)
        k_assert(sizeof_int8 = 1)
    End Sub

    Public Function bool_bytes(ByVal i As Boolean, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        Return byte_bytes(bool_byte(i), d, offset)
    End Function

    Public Function bool_bytes(ByVal i As Boolean) As Byte()
        Return byte_bytes(bool_byte(i))
    End Function

    Public Function byte_bytes(ByVal i As Byte, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        If array_size(d) >= offset + sizeof_int8 Then
            d(offset) = i
            offset += sizeof_int8
            Return True
        Else
            Return False
        End If
    End Function

    Public Function sbyte_bytes(ByVal i As SByte, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        Return byte_bytes(sbyte_byte(i), d, offset)
    End Function

    Public Function byte_bytes(ByVal i As Byte) As Byte()
        Dim o() As Byte = Nothing
        ReDim o(sizeof_uint8 - 1)
        o(0) = i
        Return o
    End Function

    Public Function sbyte_bytes(ByVal i As SByte) As Byte()
        Return byte_bytes(sbyte_byte(i))
    End Function

    Public Function uint8_bytes(ByVal i As Byte, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        Return byte_bytes(i, d, offset)
    End Function

    Public Function int8_bytes(ByVal i As SByte, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        Return sbyte_bytes(i, d, offset)
    End Function

    Public Function uint8_bytes(ByVal i As Byte) As Byte()
        Return byte_bytes(i)
    End Function

    Public Function int8_bytes(ByVal i As SByte) As Byte()
        Return sbyte_bytes(i)
    End Function

    Public Function int16_bytes(ByVal i As Int16, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        If array_size(d) >= offset + sizeof_int16 Then
            'for mono
            'Marshal.WriteXXX is 100% slower than BitConverter with memcpy
#If 0 Then
            Try
                Marshal.WriteInt16(d, offset, i)
            Catch
                Dim t() As Byte = Nothing
                t = int16_bytes(i)
                memcpy(d, offset, t)
            End Try
#End If
            Dim t() As Byte = Nothing
            t = int16_bytes(i)
            memcpy(d, offset, t)
            offset += sizeof_int16
            Return True
        Else
            Return False
        End If
    End Function

    Public Function uint16_bytes(ByVal i As UInt16, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        Return int16_bytes(uint16_int16(i), d, offset)
    End Function

    Public Function int16_bytes(ByVal i As Int16) As Byte()
        Return BitConverter.GetBytes(i)
    End Function

    Public Function uint16_bytes(ByVal i As UInt16) As Byte()
        Return int16_bytes(uint16_int16(i))
    End Function

    Public Function char_bytes(ByVal i As Char, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        If array_size(d) >= offset + sizeof_int16 Then
            'for mono
            'ditto
#If 0 Then
            Try
                Marshal.WriteInt16(d, offset, i)
            Catch
                Dim t() As Byte = Nothing
                t = char_bytes(i)
                memcpy(d, offset, t)
            End Try
#End If
            Dim t() As Byte = Nothing
            t = char_bytes(i)
            memcpy(d, offset, t)
            offset += sizeof_int16
            Return True
        Else
            Return False
        End If
    End Function

    Public Function char_bytes(ByVal i As Char) As Byte()
        Return BitConverter.GetBytes(i)
    End Function

    Public Function int32_bytes(ByVal i As Int32, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        If array_size(d) >= offset + sizeof_int32 Then
            'for mono
#If 0 Then
            Try
                Marshal.WriteInt32(d, offset, i)
            Catch
                Dim t() As Byte = Nothing
                t = int32_bytes(i)
                memcpy(d, offset, t)
            End Try
#End If
            Dim t() As Byte = Nothing
            t = int32_bytes(i)
            memcpy(d, offset, t)
            offset += sizeof_int32
            Return True
        Else
            Return False
        End If
    End Function

    Public Function uint32_bytes(ByVal i As UInt32, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        Return int32_bytes(uint32_int32(i), d, offset)
    End Function

    Public Function int32_bytes(ByVal i As Int32) As Byte()
        Return BitConverter.GetBytes(i)
    End Function

    Public Function uint32_bytes(ByVal i As UInt32) As Byte()
        Return int32_bytes(uint32_int32(i))
    End Function

    Public Function int64_bytes(ByVal i As Int64, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        If array_size(d) >= offset + sizeof_int64 Then
            'for mono
#If 0 Then
            Try
                Marshal.WriteInt64(d, offset, i)
            Catch
                Dim t() As Byte = Nothing
                t = int64_bytes(i)
                memcpy(d, offset, t)
            End Try
#End If
            Dim t() As Byte = Nothing
            t = int64_bytes(i)
            memcpy(d, offset, t)
            offset += sizeof_int64
            Return True
        Else
            Return False
        End If
    End Function

    Public Function uint64_bytes(ByVal i As UInt64, ByVal d() As Byte, Optional ByRef offset As UInt32 = 0) As Boolean
        Return int64_bytes(uint64_int64(i), d, offset)
    End Function

    Public Function int64_bytes(ByVal i As Int64) As Byte()
        Return BitConverter.GetBytes(i)
    End Function

    Public Function uint64_bytes(ByVal i As UInt64) As Byte()
        Return int64_bytes(uint64_int64(i))
    End Function
End Module
